package cn.com.chengmandian.bike.service.impl;

import cn.com.chengmandian.bike.dto.MemberCouponDto;
import cn.com.chengmandian.bike.mapper.EbMemberCouponMapper;
import cn.com.chengmandian.bike.model.EbCouponInfo;
import cn.com.chengmandian.bike.model.EbMemberCoupon;
import cn.com.chengmandian.bike.model.vo.MemberCouponVo;
import cn.com.chengmandian.bike.service.IEbCouponInfoService;
import cn.com.chengmandian.bike.service.IEbMemberCouponService;
import cn.com.chengmandian.bike.service.IEbMessageInfoService;
import cn.com.chengmandian.core.common.constants.CommonConstant;
import cn.com.chengmandian.service.bike.constants.MessageBusinessTypeEnum;
import cn.com.chengmandian.service.bike.constants.MessageChannelEnum;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 电单车运营-用户优惠券表 服务实现类
 * </p>
 *
 * @author AutoGenerator
 * @since 2021-12-15
 */
@Service
public class EbMemberCouponServiceImpl extends ServiceImpl<EbMemberCouponMapper, EbMemberCoupon> implements IEbMemberCouponService {
    @Autowired
    private EbMemberCouponMapper memberCouponMapper;

    @Autowired
    private IEbCouponInfoService couponInfoService;

    @Autowired
    private IEbMessageInfoService messageInfoService;

    @Override
    public IPage<MemberCouponVo> pages(MemberCouponDto memberCouponDto, Integer memberId) {
        return memberCouponMapper.selectCouponList(Page.of(memberCouponDto.getPageNumber(), memberCouponDto.getPageSize()), memberCouponDto, memberId);
    }

    @Override
    public List<MemberCouponVo> availableList(Integer areaId, Integer memberId, Integer infoType, String nowTime) {
        MemberCouponDto memberCouponDto = new MemberCouponDto();
        memberCouponDto.setAreaId(areaId);
        memberCouponDto.setIsUse(CommonConstant.ZERO);
        memberCouponDto.setIsInTime(CommonConstant.ONE);
        memberCouponDto.setNowTime(nowTime);
        if (infoType != null) {
            memberCouponDto.setInfoType(infoType);
        }
        return memberCouponMapper.selectCouponList(memberCouponDto, memberId);
    }

    @Override
    public List<MemberCouponVo> availableList(Integer areaId, Integer memberId, Integer infoType, String nowTime, Integer defaultRecordId) {
        MemberCouponDto memberCouponDto = new MemberCouponDto();
        memberCouponDto.setAreaId(areaId);
        memberCouponDto.setIsUse(CommonConstant.ZERO);
        memberCouponDto.setIsInTime(CommonConstant.ONE);
        memberCouponDto.setNowTime(nowTime);
        if (infoType != null) {
            memberCouponDto.setInfoType(infoType);
        }
        List<MemberCouponVo> availableCouponList = memberCouponMapper.selectCouponList(memberCouponDto, memberId);
        if(defaultRecordId != null) {
            if(availableCouponList == null) {
                availableCouponList = new ArrayList<>();
            }
            MemberCouponVo couponVo = memberCouponMapper.getByCouponDetail(defaultRecordId);
            availableCouponList.add(0, couponVo);
        }
        return availableCouponList;
    }

    @Override
    public MemberCouponVo findOneCoupon(Integer areaId, Integer memberId, Integer type, BigDecimal thresholdMoney) {
        return memberCouponMapper.fetchAvailableCoupon(areaId, memberId, type, thresholdMoney);
    }

    @Override
    public MemberCouponVo getByCouponId(Integer couponRecordId) {
        return memberCouponMapper.getByCouponDetail(couponRecordId);
    }

    @Override
    public void useCoupon(Integer couponId) {
        this.update(new LambdaUpdateWrapper<EbMemberCoupon>().set(EbMemberCoupon::getIsUse, CommonConstant.ONE)
                .set(EbMemberCoupon::getUseTime, new Date()).eq(EbMemberCoupon::getId, couponId));
    }

    /**
     * 注册送优惠券
     * @param memberId
     */
    @Override
    public void createByRegister(Integer areaId, Integer memberId) {
        List<EbCouponInfo> list = couponInfoService.selectChannelList(areaId, CommonConstant.TWO);
        if (list.size() == 0) return;
        Date now = new Date();
        for(EbCouponInfo couponInfo : list) {
            EbMemberCoupon memberCoupon = new EbMemberCoupon();
            memberCoupon.setCouponId(couponInfo.getId());
            memberCoupon.setAreaId(areaId);
            memberCoupon.setMemberId(memberId);
            memberCoupon.setCouponMoney(couponInfo.getCouponMoney());
            memberCoupon.setCouponRate(couponInfo.getCouponRate());
            memberCoupon.setStartTime(new Date());
            if (couponInfo.getExpireType().equals(CommonConstant.ONE)) {
                memberCoupon.setEndTime(DateUtil.offsetDay(now, couponInfo.getExpireDays()));
            } else if (couponInfo.getExpireType().equals(CommonConstant.TWO)) {
                memberCoupon.setEndTime(couponInfo.getExpireTime());
            }
            this.save(memberCoupon);
            couponInfoService.updateSendAmount(couponInfo.getId());

            messageInfoService.addSys(memberId, MessageChannelEnum.SYS,
                    "尊敬的用户，您于 "  + DateUtil.now() + " 收到一张新的优惠券，有效期至 " + memberCoupon.getEndTime()  + " ，感谢您的支持与信任！",
                    null, MessageBusinessTypeEnum.COUPON, memberCoupon.getId());
        }
    }

    @Override
    public MemberCouponVo getByCouponId(Integer areaId, Integer memberId, Integer type, BigDecimal thresholdMoney, Integer couponRecordId, Date useTime) {
        MemberCouponVo memberCouponVo = new MemberCouponVo();
        EbMemberCoupon memberCoupon = this.getOne(new LambdaQueryWrapper<EbMemberCoupon>()
                .eq(EbMemberCoupon::getAreaId, areaId)
                .eq(EbMemberCoupon::getMemberId, memberId)
                .eq(EbMemberCoupon::getId, couponRecordId));
        Assert.notNull(memberCoupon, "优惠券不存在");
        Assert.isTrue(memberCoupon.getIsUse().equals(CommonConstant.ZERO), "优惠券已使用");
        EbCouponInfo couponInfo = couponInfoService.getById(memberCoupon.getCouponId());
        Assert.notNull(couponInfo, "优惠券配置不存在");
        Assert.isTrue(couponInfo.getType().equals(type), "优惠券类型不存在");
        Assert.isTrue(couponInfo.getThresholdMoney().compareTo(thresholdMoney) <= 0, "未达到优惠券使用门槛");
        Assert.isTrue(memberCoupon.getStartTime().before(useTime) && memberCoupon.getEndTime().after(useTime), "此订单产生时间不在优惠券使用范围内");
        BeanUtils.copyProperties(memberCoupon, memberCouponVo);

        memberCouponVo.setCouponName(couponInfo.getName());
        memberCouponVo.setInfoType(couponInfo.getType());
        memberCouponVo.setCouponType(couponInfo.getCouponType());
        memberCouponVo.setThresholdMoney(couponInfo.getThresholdMoney());

        return memberCouponVo;
    }

    @Override
    public void cancelUseCoupon(Integer couponId) {
        this.update(new LambdaUpdateWrapper<EbMemberCoupon>().set(EbMemberCoupon::getIsUse, CommonConstant.ZERO)
                .set(EbMemberCoupon::getUseTime, null).eq(EbMemberCoupon::getId, couponId));
    }
}
